import json
import os, sys

pwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(pwd + '../')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'riscv_build_dataset.settings')

import django

django.setup()

from obs.models import obs_package, obs_job_history
from riscv_build_dataset.util import read_timestamp
from tqdm import tqdm

import requests, base64
from requests.adapters import HTTPAdapter

session = requests.Session()
session.mount('https://', HTTPAdapter(max_retries=5))
cookies = {
    '_obs_api_session': os.environ.get('OBS_COOKIE'),
}

OBS_username = os.environ.get('OBS_USERNAME')
OBS_password = os.environ.get('OBS_PASSWORD')
credential = OBS_username + ':' + OBS_password
b64credential = base64.b64encode(credential.encode("ascii")).decode("ascii")
print(b64credential)


headers = {
    'Accept': 'application/xml',
    'charset': 'utf-8',
    'Authorization': 'Basic ' + b64credential,
}


def package_all_build_history(package_name):
    package_history = obs_job_history.objects.filter(package__package_name=package_name).order_by('-build_time')
    # print(package_history)
    for build in package_history:
        print(build.package.project.project_name, build.package_revision, read_timestamp(build.build_time),
              build.build_status_code, sep='\t')
    return package_history


def failed_then_success_pairs(histories):
    pairs = []
    len = histories.count()
    if len < 2:
        return None
    for i in range(len - 1):
        if histories[i].build_status_code == 'succeeded' and histories[i + 1].build_status_code == 'failed':
            # print(f'Success build time:{histories[i].build_time} using revision:{histories[i].package_revision},'
            #       f'Failed build time:{histories[i + 1].build_time} using revision:{histories[i + 1].package_revision}')
            pairs.append({
                'success': {
                    'id': histories[i].id,
                    'project': histories[i].project.project_id,
                    'project_name': histories[i].project.project_name,
                    'package': histories[i].package.id,
                    'package_name': histories[i].package.package_name,
                    'package_revision': histories[i].package_revision,
                    'build_time': histories[i].build_time,
                    'build_status_code': histories[i].build_status_code,
                    'build_reason': histories[i].build_reason,
                    'build_duration': histories[i].build_duration,
                },
                'fail': {
                    'id': histories[i + 1].id,
                    'project': histories[i + 1].project.project_id,
                    'project_name': histories[i + 1].project.project_name,
                    'package': histories[i + 1].package.id,
                    'package_name': histories[i + 1].package.package_name,
                    'package_revision': histories[i + 1].package_revision,
                    'build_time': histories[i + 1].build_time,
                    'build_status_code': histories[i + 1].build_status_code,
                    'build_reason': histories[i + 1].build_reason,
                    'build_duration': histories[i + 1].build_duration,
                }
            })

    # print(pairs)
    return pairs


def get_pairs_from_db():
    pairs = []
    packages = obs_package.objects.all()
    for package in tqdm(packages):
        package_history = obs_job_history.objects.filter(package=package).order_by('-build_time')
        p = failed_then_success_pairs(package_history)
        if p and len(p):
            pairs.extend(p)

    with open('failed_success_pairs.json', 'w') as f:
        json.dump(pairs, f, indent=2)
        f.close()


def read_pairs_from_file():
    f = open('failed_success_pairs.json', 'r')
    pairs = json.load(f)
    f.close()

    print(f'There are {len(pairs)} failed then success pairs.')
    return pairs


def analysis_pairs(pairs):
    for pair in pairs:
        if pair.get('success').get('package_revision') != pair.get('fail').get('package_revision'):
            # Revision not the same between success and failed build.
            project_name = pair.get('success').get('project_name')
            package_name = pair.get('success').get('package_name')
            orev = pair.get('fail').get('package_revision')
            rev = pair.get('success').get('package_revision')
            url = f'https://build.tarsier-infra.com/source/{project_name}/{package_name}?cmd=diff&orev={orev}&rev={rev}&expand=0'
            resp = session.post(url, headers=headers, timeout=2)
            print(resp.text)
            exit(0)


if __name__ == '__main__':
    # url = f'https://build.tarsier-infra.com/source/openEuler:22.03/mpich?cmd=diff&orev=2&rev=6&expand=0'
    # resp = session.post(url, headers=headers)
    # print(resp.text)
    #
    # exit(0)

    get_pairs_from_db()
    pairs = read_pairs_from_file()
    analysis_pairs(pairs)
